<?php
class Loader
{
    private static $_instance = null;

    protected $_loadedCache = array();

    private function __construct()
    {}

    public function config($name)
    {
        if ($val = Config::get($name))
        {
            return $val;
        }

        return false;
    }

	public function model($modelPath)
	{
        $model = basename($modelPath);
        $path = 'model/' . dirname($modelPath);

        return $this->_loadClass($model, $path, APPLICATION_PATH);
	}

	public function library($libraryPath)
	{
        $library = basename($libraryPath);
        $path = 'library/' . dirname($libraryPath);

		return $this->_loadClass($library, $path, SYSTEM_PATH);
	}

    public function helper($helperPath)
    {
        Loader::loadFile(SYSTEM_PATH . 'helper/' . $helperPath . '.php');
    }

    public function database()
    {
        if ($this->isLoaded('database/database'))
        {
            return $this->_loadedCache['database/database'];
        }

        // Check config
        $dbConfig = Config::get('db');

        if (is_array($dbConfig) && isset($dbConfig['host'])
            && isset($dbConfig['username']) && isset($dbConfig['password'])
            && isset($dbConfig['dbname'])
        )
        {
            $database = $this->_loadClass('Database', 'database', SYSTEM_PATH);

            $database->setConnection('mysql', $dbConfig['host'],
                $dbConfig['username'], $dbConfig['password'],
                $dbConfig['dbname']
            );

            return $database;
        }

        throw new MyException('Error: Database config');
    }

    public function isLoaded($path)
    {
        if (isset($this->_loadedCache[$path]))
        {
            return true;
        }

        return false;
    }

    public static function getInstance()
    {
        if (self::$_instance == null)
        {
            self::$_instance = new self;
        }

        return self::$_instance;
    }

    public function unload()
    {
        // Close database connection
        if (isset($this->_loadedCache['database/database']))
        {
            $this->_loadedCache['database/database']->close();
        }
    }

    public static function loadFile($filePath)
    {
        if (!file_exists($filePath))
        {
            throw new Exception('Can not load file: ' . $filePath . '.');
        }

        include_once($filePath);

        return true;
    }

    protected function _loadClass($class, $pathName, $basePath)
    {
        $path = strtolower($pathName . '/' . $class);

        if ($this->isLoaded($path))
        {
            return $this->_loadedCache[$path];
        }

        Loader::loadFile($basePath . $path . '.php');

        if (!class_exists($class))
        {
            throw new MyException('Can not load class: ' . $class);
        }

        $this->_loadedCache[$path] = new $class();

        return $this->_loadedCache[$path];
    }
}